import { IAppState, ICommand } from "@shared/message-bus/type";
import { useEffect, useState } from "react";

interface IMod {
    sendCommand: <K extends keyof ICommand>(
        command: K,
        data?: ICommand[K]
    ) => void;
    getAppState: () => IAppState;
    subscribeAppState: (keys: (keyof IAppState)[]) => void;
    onStateChange: (
        cb: (appState: IAppState, changedAppState: IAppState) => void
    ) => void;
    offStateChange: (
        cb: (appState: IAppState, changedAppState: IAppState) => void
    ) => void;
}

const mod = window["@shared/message-bus/extension" as any] as unknown as IMod;

export function useAppState() {
    const [appState, setAppState] = useState(mod.getAppState);

    useEffect(() => {
        mod.onStateChange(setAppState);
        setAppState(mod.getAppState);
        return () => {
            mod.offStateChange(setAppState);
        };
    }, []);

    return appState;
}

export function useAppStatePartial<K extends keyof IAppState>(key: K) {
    const [appState, setAppState] = useState<IAppState[K]>(
        mod.getAppState()?.[key],
    );
    useEffect(() => {
        const cb = (appState: IAppState, changedAppState: IAppState) => {
            if (key in changedAppState) {
                setAppState(mod.getAppState()[key]);
            }
        };

        mod.onStateChange(cb);
        setAppState(mod.getAppState()?.[key]);
        return () => {
            mod.offStateChange(cb);
        };
    }, []);

    return appState;
}

const messageBus = {
    sendCommand: mod.sendCommand,
    subscribeAppState: mod.subscribeAppState,
    onStateChange: mod.onStateChange,
    offStateChange: mod.offStateChange,
};

export default messageBus;
